/**
 * Created by sine on 2017/9/1.
 */

/**
 * 基于 eventHandler 的函数组
 */


var isun = {};

(function(){


    //TODO 应当返回一个事件监听状态
    /**
     * @param target
     * @param act
     * @param queueName 队列名称
     * @param callbacks 回调函数数组
     *      callbacks.onstart 拖拽开始时
     *      callbacks.onmove 拖拽中移动时
     *      callbacks.onend 拖拽结束时
     */
    isun.drag = function (target, act, queueName, callbacks){
        if(!target)
            return;
        if(target.css("position") === "static"){
            console.err("position could not be static");
            return;
        }
        if(!act){
            act = target;
        }else{
            if(typeof act === "string"){
                callbacks = queueName;
                queueName = act;
                act = target;
            }
        }
        if(!callbacks)
            callbacks = {};

        target = $(target);
        act = $(act);

        // target.$init();
        act.$init(queueName);

        var cox, coy, tox, toy;
        act.$on("mousedown",down, queueName).$add(queueName);
        $(document.body).$add(queueName);

        function down(e){
            cox = e.pageX;
            coy = e.pageY;
            tox = target[0].offsetLeft;
            toy = target[0].offsetTop;

            $(document.body).$off("mousemove", move, queueName);
            $(document.body).$off("mouseup", up, queueName);
            $(document.body).$on("mousemove", move, queueName);
            $(document.body).$on("mouseup", up, queueName);

            if(callbacks.onstart)
                callbacks.onstart.call(target[0], e);
        }
        function move(e){
            target.css({
                left: tox + e.pageX - cox,
                top: toy + e.pageY - coy
            });
            if(callbacks.onmove)
                callbacks.onmove.call(target[0], e);
        }
        function up(e){
            $(document.body).$off("mousemove", move, queueName);
            $(document.body).$off("mouseup", up, queueName);
            if(callbacks.onend)
                callbacks.onend.call(target[0], e);
        }

        //TODO 在act和body被加入事件响应队列后，并没有被移除
        return {
            clear: function(){
                act.$off("mousedown", down, queueName);
                $(document.body).$off("mousemove", move, queueName);
                $(document.body).$off("mouseup", up, queueName);
            }
        };
    };

    /**
     * 获取点在元素的区域的编号   上：1  右：2  下：3  左：4   不在矩形内：0
     * @param p 相对页面左上角的点的坐标
     * @param el
     * @param edgeWidth [上, 右, 下, 左]
     * @return {index: number, dist: number}
     */
    isun.getPortionIndex = function(p, el, edgeWidth){
        //slop [左上, 右上, 右下, 左下]

        var ltpp = isun.getPosition(el);
        var rbpp = [ltpp[0] + el.offsetWidth, ltpp[1] + el.offsetHeight];

        if(edgeWidth){
            if(typeof edgeWidth === "number")
                edgeWidth = [edgeWidth, edgeWidth, edgeWidth, edgeWidth];
            var ltpp2 = [ltpp[0] + edgeWidth[3], ltpp[1] + edgeWidth[0]];
            var rbpp2 = [rbpp[0] - edgeWidth[1], rbpp[1] - edgeWidth[2]];
        }

        // if(expansion){
        //     ltpp[0] -= expansion[0];
        //     ltpp[1] -= expansion[1];
        //     rbpp[0] += expansion[0];
        //     rbpp[1] += expansion[1];
        // }

        // var center = [(ltpp[0] + rbpp[0]) / 2, (ltpp[1] + rbpp[1]) / 2];

        if(p[0] >= ltpp[0] &&
            p[0] <= rbpp[0] &&
            p[1] >= ltpp[1] &&
            p[1] <= rbpp[1] && !(edgeWidth &&
                    p[0] >= ltpp2[0] &&
                    p[0] <= rbpp2[0] &&
                    p[1] >= ltpp2[1] &&
                    p[1] <= rbpp2[1]
            )
            // (!exclusion ||
            //     Math.abs(p[0] - center[0]) > exclusion[0] / 2 ||
            //     Math.abs(p[1] - center[1]) > exclusion[1] / 2
            // )
        ){
            var slop_corner = [
                Math.abs((p[1] - ltpp[1]) / (p[0] - ltpp[0])),
                Math.abs((p[1] - ltpp[1]) / (p[0] - rbpp[0])),
                Math.abs((p[1] - rbpp[1]) / (p[0] - rbpp[0])),
                Math.abs((p[1] - rbpp[1]) / (p[0] - ltpp[0]))
            ];
            var slop = el.offsetHeight / el.offsetWidth;
            var index;

            if(slop_corner[0] <= slop){
                if(slop_corner[1] <= slop)
                    index = 1;
                else if(slop_corner[3] <= slop)
                    index = 2;
            }else{
                if(slop_corner[3] > slop)
                    index = 4;
                else
                    index = 3;
            }
            var dist;
            switch(index){
                case 1:
                    dist = p[1] - ltpp[1];
                    break;
                case 2:
                    dist = rbpp[0] - p[0];
                    break;
                case 3:
                    dist = rbpp[1] - p[1];
                    break;
                case 4:
                    dist = p[0] - ltpp[0];
                    break;
            }
            return {index: index, dist: dist};
        }else{
            return {index: 0, dist: 0};
        }
    };

    isun.getPosition = function (el){
        el = $(el)[0];
        var result = [el.offsetLeft, el.offsetTop];
        var root = document.documentElement;
        if($(el).css("position") === "fixed"){
            result[0] += window.scrollY || root.scrollTop;
            result[1] += window.scrollX || root.scrollLeft;
        }else

            $(el).parents().each(function(){
                var position = $(this).css("position");
                if(position === "fixed"){

                }else if(position !== "static"){
                    result[0] += this.offsetLeft;
                    result[1] += this.offsetTop;
                }
            });
        return result;
    };


    isun.delEmpty = function(col, stopSelector){
        col = $(col);
        if(col.length === 1){
            var parent;
            while(!col.children().length){
                parent = col.parent();
                col.remove();
                if(col.is(stopSelector) || col.parent().is("body"))
                    break;
                col = parent;
            }
        }
    };

    isun.toJsonString = function (obj){
        switch(typeof obj){
            case "undefined":
            case "number":
            case "boolean":
                return String(obj);
            case "string":
                return "\"" + obj + "\"";
            case "object":
                if(obj == null)
                    return String(obj);
                var str;
                if(obj instanceof Array){
                    str = "[";
                    obj.forEach(function(v){
                        str += isun.toJsonString(v) + ",";
                    });
                    if(str.length > 1)
                        str = str.substr(0, str.length - 1);
                    str += "]";
                }else{
                    str = "{";
                    Object.keys(obj).forEach(function(key){
                        str += "\"" + key + "\":" + isun.toJsonString(obj[key]) + ",";
                    });
                    if(str.length > 1){
                        str = str.substr(0, str.length - 1);
                    }
                    str += "}";
                }
                return str;
            default:
                throw "type error";
        }


        // if(typeof obj !== "object" || obj == null){
        //     return String(obj);
        // }else{
        //
        // }
    };


    isun.reform = function(row){

    };

    // isun.getBorderCover = function(el){
    //     el = $(el)[0];
    //     var position = isun.getPosition(el);
    //     return $("<div/>").css({
    //         position: "absolute",
    //         left: position[0] + "px",
    //         top: position[1] + "px",
    //         zIndex: "999999999"
    //     });
    // };

    /**
     * 从 els 中找出距离 p 最近的元素
     * @param p
     * @param els
     * @param direction: "vertical" = 0 | "horizontal" = 1 | "center" = 2
     */
    isun.getNearest = function(p, els, direction){

        switch(direction){
            case 0:
            case "vertical":
                $(els).each(function(){

                });
                break;
            case 1:
            case "horizontal":

                break;
            case 2:
            case "center":

                break;
        }
    };
})();
